home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / docs / keyboard.txt < prev    next >
Internet Message Format  |  1995-04-17  |  5KB

  1. From: sayanna@studaff.und.ac.za (Mr Alvin Sayanna)
  2. Newsgroups: comp.os.msdos.programmer
  3. Subject: INFO: How to detect Key Press/Releases
  4. Date: Tue, 9 Aug 1994 07:47:09 GMT
  5.  
  6. Hi all,
  7.  
  8. Seems that many people want advice on Keyboard Interrupts. I also
  9. did a short time ago and with the help I got then I figured out how
  10. to do a few nifty things with interrupts. I have written up a short
  11. document (below) that will hopefully help others start on the very
  12. interesting road to interrupt programming.
  13.  
  14. Just one note. I AM A BEGINNER ! The information that is found below
  15. is what I have gained from tinkering around and asking questions.
  16. If there are any points that are incorrect I will be grateful you would
  17. correct me. (oh yes...the program included works too !)
  18.  
  19. Ok...Here it is...
  20.  
  21. ---------------------------------------------------------------------------
  22.                  HOW THE HECK TO MESS UP MY KEYBOARD ;^)
  23.                        by Me... (Alvin Sayanna)
  24. ---------------------------------------------------------------------------
  25.  
  26. What happens when a key is pressed ?
  27. ------------------------------------
  28.  
  29. Interrupt 9 (IRQ1) is generated when data is received from the keyboard.
  30. This data is normally a scan code that is produced from a key press or
  31. release. If the BIOS supports an enhanced keyboard it calls INT 15h
  32. (service 4Fh) before further processing of the key.
  33.  
  34. Interrupt 15h service 4Fh makes allowance for keyboard translation. When
  35. called AL will contain the scan code with the Carry Flag set to 1.
  36. On return INT 15h returns the scan code in AL with the Carry Flag set.
  37. If the Carry flag is clear on return from INT 15h then INT 9 ignores
  38. the keystroke.
  39.  
  40. So what does this all mean ?
  41. ----------------------------
  42.  
  43. To intercept a key press or to detect a key release we can insert our very
  44. own procedure into INT 15h to catch the scan code. Once we have intercepted
  45. this scan code we can do anything with it eg: We can cause INT 9 to ignore
  46. it, we can change the code to some other code, we can detect if this was a
  47. key release, etc.
  48.  
  49. So how do we actually do that ?
  50. -------------------------------
  51.  
  52. Ok...decide what we want to do with the key...for example we want to detect
  53. when a key is released. We then write out our little procedure in PASCAL
  54. (*grin* that's about the easiest for me).
  55.  
  56. But wait...how do we know when a key was released anyway ? Well when a
  57. key is released bit 7 of the scan code in AL is set. So all we have to do
  58. is check bit 7 of every scan code we intercept and here is a small program
  59. to demonstrate just that...
  60.  
  61.  
  62. ----------our program---------
  63.  
  64. {$M $400,0,0}                                <---set up a 1k stack
  65. Uses Crt, Dos;                               <---we all know what this is :)
  66.  
  67. Var KbdIntVec : Procedure;
  68.  
  69.  
  70. {$F+}                                        <---note the Far Call
  71. Procedure Catch_Int_15(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP : Word); Interrupt;
  72.   Begin
  73.     If Hi(AX) = $4f then                     <---pass all other INT15 services
  74.                                                  to the orig handler. We are
  75.                                                  only interested in service
  76.                                                  4Fh.
  77.          If (Lo(AX) and 128) = 128 then      <---check if bit 7 is set
  78.            Begin
  79.              Sound(1000);                    <---It is, so let's make a beep
  80.              Delay(1);
  81.              NoSound;
  82.            End;
  83.     Inline($9C);                             <---push flags because we're done
  84.     KbdIntVec;                               <---hand back to the original
  85.   End;                                           INT 15h handler
  86. {$F-}
  87.  
  88.  
  89. Begin
  90.   GetIntVec($15,@KbdIntVec);
  91.   SetIntVec($15,Addr(Catch_Int_15));
  92.   Keep(0); { Terminate, stay resident }
  93. End.
  94.  
  95. --------end of our program---------
  96.  
  97. ...and there we go. We have just set up a program that would cause a key
  98. release be followed by a loud *BEEP* :)
  99.  
  100. Ok...let's go through the program...
  101.  
  102. GetIntVec gets the address of the original INT 15h handler and stores it
  103. in our variable KbdIntVec. We then set the handler address for INT 15h to
  104. point to our procedure namely Catch_Int_15 and we end the program with
  105. Keep which exits but leaves the program resident in memory. And now we
  106. have INT 15h calling our nifty little procedure !
  107.  
  108. When our procedure gets called we check AH for the service number. Since
  109. we are only interested in service 4Fh we pass all others to the original
  110. handler for INT 15h which you will remember we stored in KbdIntVec. If
  111. we detect service 4Fh we then proceed to check if the scan code (which
  112. is in AL) has bit 7 set. If it has then we know that this was a key
  113. release ! Wow...simple isn't it ? *grin*. Well to proclaim our achievement
  114. to the world we add a little sound :) and cause the key release to make
  115. a BEEP. Now we are done and like good little aspiring programmers we pass
  116. control back to the original handler for INT 15h. And folks...that's it !
  117.  
  118.  
  119. Where do we go from here ?
  120. --------------------------
  121.  
  122. Well two EXCELLENT sources of information on interrupts are
  123.  
  124.          1) Ralf Brown's Interrupt List
  125.                   INTER36A.ZIP to INTER36D.ZIP
  126.  
  127.          2) HelpPc 2.10 - Quick Reference Utility by David Jurgens
  128.                   HELPPC21.ZIP
  129.  
  130.          both of which are obtainable from any of the large ftp sites.
  131.  
  132.  
  133. Well that's it...
  134.  
  135. See ya,
  136. Alvin
  137.  
  138. PS: please attempt to withhold flames 8-) and rather send constructive
  139. comments and help.
  140.  
  141.